package com.sun.service.impl;

import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sun.common.BaseContext;
import com.sun.common.Exception.CustomException;
import com.sun.entity.QuartzBean;
import com.sun.mapper.QuartzMapper;
import com.sun.service.QuartzService;
import com.sun.utils.QuartzUtils;
import org.quartz.JobDataMap;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.util.List;

/**
 * @Project: hospitalDrugInformationManagement
 * @Author: 86178
 * @Date: 2023/3/29 18:10
 * @FileName: QuartzServiceImpl
 * @Description: ""
 */
@Service
public class QuartzServiceImpl extends ServiceImpl<QuartzMapper, QuartzBean> implements QuartzService {

    @Autowired
    private Scheduler scheduler;

    @Autowired
    private QuartzMapper quartzMapper;

    /**
     * 项目启动时，初始化定时器 主要是防止手动修改数据库导致未同步到定时任务处理（注：不能手动修改数据库ID和任务组名，否则会导致脏数据）
     */
    @PostConstruct
    public void init() {
        try {
            scheduler.clear();
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
        List<QuartzBean> jobList = this.list();
        for (QuartzBean job : jobList) {
            QuartzUtils.createScheduleJob(scheduler, job);
        }
    }

    @Override
    public int insertJob(QuartzBean quartzBean) {
        quartzBean.setStatus(String.valueOf(0));
        quartzBean.setJobId(IdWorker.getId());
        quartzBean.setCreateUser(BaseContext.getCurrentId());
        int row = quartzMapper.insert(quartzBean);
        if (row > 0) {
            try {
                QuartzUtils.createScheduleJob(scheduler, quartzBean);
            } catch (Exception e) {
                throw new CustomException("创建失败");
            }
        }
        return row;
    }

    @Override
    public int updateJob(QuartzBean quartzBean) {
        int row = quartzMapper.updateById(quartzBean);
        // 判断是否存在
        JobKey jobKey = QuartzUtils.getJobKey(quartzBean.getJobName(), quartzBean.getJobGroup());
        try {
            if (scheduler.checkExists(jobKey)) {
                // 防止创建时存在数据问题 先移除，然后在执行创建操作
                scheduler.deleteJob(jobKey);
            }
            QuartzUtils.createScheduleJob(scheduler, quartzBean);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
        if (row > 0) {
            QuartzUtils.updateScheduleJob(scheduler, quartzBean);
        }
        return row;
    }

    /**
     * 暂停任务
     *
     * @param quartzBean 调度信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int pauseJob(QuartzBean quartzBean) {
        String jobName = quartzBean.getJobName();
        String jobGroup = quartzBean.getJobGroup();
        quartzBean.setStatus(String.valueOf(1));
        int rows = quartzMapper.updateById(quartzBean);
        if (rows > 0) {
            QuartzUtils.pauseScheduleJob(scheduler, jobName, jobGroup);
        }
        return rows;
    }

    /**
     * 恢复任务
     *
     * @param job 调度信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int resumeJob(QuartzBean job) throws SchedulerException {
        String jobName = job.getJobName();
        String jobGroup = job.getJobGroup();
        job.setStatus(String.valueOf(0));
        int rows = quartzMapper.updateById(job);
        if (rows > 0) {
            QuartzUtils.resumeScheduleJob(scheduler, jobName, jobGroup);
        }
        return rows;
    }

    /**
     * 删除任务后，所对应的trigger也将被删除
     *
     * @param job 调度信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteJob(QuartzBean job) throws SchedulerException {
        String jobName = job.getJobName();
        String jobGroup = job.getJobGroup();
        int rows = quartzMapper.deleteById(job.getJobId());
        if (rows > 0) {
            QuartzUtils.deleteScheduleJob(scheduler, jobName, jobGroup);
        }
        return rows;
    }

    /**
     * 批量删除调度信息
     *
     * @param jobIds 需要删除的任务ID
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteJobByIds(Long[] jobIds) throws SchedulerException {
        for (Long jobId : jobIds) {
            QuartzBean job = quartzMapper.selectById(jobId);
            deleteJob(job);
        }
    }

    /**
     * 任务调度状态修改
     *
     * @param job 调度信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int changeStatus(QuartzBean job) throws SchedulerException {
        int rows = 0;
        String status = job.getStatus();
        if ("0".equals(status)) {
            rows = resumeJob(job);
        } else if ("1".equals(status)) {
            rows = pauseJob(job);
        }
        return rows;
    }

    /**
     * 立即运行任务
     *
     * @param job 调度信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean run(QuartzBean job) {
        boolean result = false;
        String jobName = job.getJobName();
        String jobGroup = job.getJobGroup();
        QuartzBean properties = quartzMapper.selectById(job.getJobId());
        // 参数
        JobDataMap dataMap = new JobDataMap();
        dataMap.put("TASK_PROPERTIES", properties);
        JobKey jobKey = QuartzUtils.getJobKey(jobName, jobGroup);
        try {
            if (scheduler.checkExists(jobKey)) {
                result = true;
                scheduler.triggerJob(jobKey, dataMap);
            }
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
        return result;
    }
}
